#include "TcpConnection.h"
#include "Logger.h"
#include "Socket.h"
#include "Channel.h"

#include <unistd.h>
#include <functional>

static EventLoop* CheckLoopNotNull(EventLoop* loop)
{
    if(loop == nullptr){
        LOG_FATAL("%s:%s:%d TcpConnection Loop is nullptr", __FILE__, __FUNCTION__, __LINE__);
    }
    return loop;
}



TcpConnection::TcpConnection(EventLoop* loop
                , const std::string& name
                , int sockfd
                , const InetAddress& localAddr
                , const InetAddress& peerAddr)
    : loop_(CheckLoopNotNull(loop))
    , name_(name)
    , state_(kConnecting)
    , reading_(true)
    , socket_(new Socket(sockfd))
    , channel_(new Channel(loop_, sockfd))
    , localAddr_(localAddr)
    , peerAddr_(peerAddr)
    , highWaterMark_(HIGHWATERMARK)
    // , inputBuffer_()
    // , outputBuffer_()
{
    //给channel设置相应的回调行数，poller给channel通知感兴趣的事件发生时，channel会回调相应的操作函数
    channel_->setReadCallback(
        std::bind(&TcpConnection::handleRead, this, std::placeholders::_1)
    );
    channel_->setWriteCallback(
        std::bind(&TcpConnection::handleWrite, this)
    );
    channel_->setCloseCallback(
        std::bind(&TcpConnection::handleClose, this)
    );
    channel_->setErrorCallback(
        std::bind(&TcpConnection::handleError, this)
    );
    LOG_INFO("TcpConnection::ctor[%s] at fd = %d\n", name_.c_str(), sockfd);
    socket_->setKeepAlive(true);
}

TcpConnection::~TcpConnection(){
    //loop_变量是一个指针，并且这个指针是从外部传入进来的。所有本类不对它负责
    //构造函数中new出来的Socket和Channel通过智能指针管理了，不需要关心
    LOG_INFO("TcpConnection::ctor[%s] at fd = %d state = %d\n", name_.c_str(), channel_->fd(), state_);
}